package com.xbongbong.paas.connection.service.imp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.admin.domain.entity.LowCodeRetaionEntity;
import com.xbongbong.admin.model.LowCodeRetaionModel;
import com.xbongbong.admin.pojo.LowCodeConfigRetaionPojo;
import com.xbongbong.paas.connection.enums.LowCodeOperationTypeEnum;
import com.xbongbong.paas.connection.pojo.LowCodeConfigPojo;
import com.xbongbong.paas.connection.pojo.dto.CloudCodeLowCodeConfigListDTO;
import com.xbongbong.paas.connection.pojo.dto.LowCodeInstallDTO;
import com.xbongbong.paas.connection.pojo.vo.CloudCodeLowCodeIsDeveloperVO;
import com.xbongbong.paas.connection.pojo.vo.CompanyInfoVO;
import com.xbongbong.paas.connection.service.ICloudCodeService;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.feign.UserFeignClient;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.lowcode.DeveloperService;
import com.xbongbong.paas.lowcode.LowCodeConfigService;
import com.xbongbong.paas.model.CustomButtonActionModel;
import com.xbongbong.paas.model.CustomButtonModel;
import com.xbongbong.paas.model.LowCodeActionSettingModel;
import com.xbongbong.paas.model.LowCodeJsFileModel;
import com.xbongbong.paas.pojo.dto.UserInfoDTO;
import com.xbongbong.paas.pojo.vo.UserInfoVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.UserService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.actionsetting.pojo.LowCodeActionSettingPojo;
import com.xbongbong.pro.custombutton.pojo.CustomButtonActionPojo;
import com.xbongbong.pro.custombutton.pojo.CustomButtonPojo;
import com.xbongbong.pro.department.pojo.DepartmentUserPojo;
import com.xbongbong.pro.developer.pojo.DeveloperPojo;
import com.xbongbong.pro.developer.pojo.dto.DeveloperListDTO;
import com.xbongbong.pro.developer.pojo.vo.DeveloperListVO;
import com.xbongbong.pro.domain.entity.CustomButtonActionEntity;
import com.xbongbong.pro.domain.entity.CustomButtonEntity;
import com.xbongbong.pro.domain.entity.LowCodeActionSettingEntity;
import com.xbongbong.pro.domain.entity.LowCodeJsFileEntity;
import com.xbongbong.pro.enums.errorcodes.PerformanceErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateCenterErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.lowcode.LowCodeActionTypeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.lowcodeconfig.pojo.dto.LowCodeConfigListDTO;
import com.xbongbong.pro.lowcodeconfig.pojo.vo.LowCodeConfigListVO;
import com.xbongbong.pro.lowcodejsfile.pojo.LowCodeJsFilePojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.CompanyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 云叩与pro交互
 * @author 李少杰
 * @version v1.0.0
 * @date 2022/2/11 11:16
 */
@Service("iCloudCodeService")
public class CloudCodeServiceImpl implements ICloudCodeService {
    private static final Logger LOG = LoggerFactory.getLogger(CloudCodeServiceImpl.class);
    @Resource
    private LowCodeConfigService lowCodeConfigService;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private LowCodeJsFileModel lowCodeJsFileModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private CustomButtonModel customButtonModel;
    @Resource
    private CustomButtonActionModel customButtonActionModel;
    @Resource
    private LowCodeActionSettingModel lowCodeActionSettingModel;
    @Resource
    private LowCodeRetaionModel lowCodeRetaionModel;
    @Resource
    private DeveloperService developerService;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private UserService userService;


    @Override
    public CloudCodeLowCodeIsDeveloperVO isDeveloper(@RequestBody @Valid DeveloperListDTO developerListDTO) throws XbbException {
        CloudCodeLowCodeIsDeveloperVO cloudCodeLowCodeIsDeveloperVO = new CloudCodeLowCodeIsDeveloperVO();
        String corpid = developerListDTO.getCorpid();
        String userId = developerListDTO.getUserId();
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setCorpid(corpid);
        userInfoDTO.setUserId(userId);
        UserInfoVO userInfo = userService.getUserInfo(userInfoDTO);
        UserVO loginUser = userInfo.getUser();
        developerListDTO.setLoginUser(loginUser);
        DeveloperListVO developerListVO = developerService.list(developerListDTO);
        List<DeveloperPojo> developerList = developerListVO.getDeveloperList();
        cloudCodeLowCodeIsDeveloperVO.setDeveloper(0);
        for (DeveloperPojo developer : developerList) {
            DepartmentUserPojo user = developer.getUser();
            if ( Objects.isNull(user) ) {
                continue;
            }
            if ( Objects.equals(user.getId(), userId) ) {
                cloudCodeLowCodeIsDeveloperVO.setDeveloper(1);
                break;
            }
        }
        return cloudCodeLowCodeIsDeveloperVO;
    }

    @Override
    public CompanyInfoVO companyInfo(String corpid) throws XbbException {
        CompanyInfoVO companyInfoVO = new CompanyInfoVO();
        if (StringUtil.isEmpty(corpid)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100011);
        }
        CompanyEntity companyEntity = companyModel.getByKey(corpid);
        if (Objects.isNull(companyEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100011);
        }
        BeanUtil.copyProperties(companyEntity, companyInfoVO);
        return companyInfoVO;
    }

    @Override
    public LowCodeConfigListVO lowCodeConfigList(CloudCodeLowCodeConfigListDTO cloudCodeLowCodeConfigListDTO) throws XbbException {
        LowCodeConfigListDTO lowCodeConfigListDTO = new LowCodeConfigListDTO();
        BeanUtil.copyProperties(cloudCodeLowCodeConfigListDTO, lowCodeConfigListDTO);
        return lowCodeConfigService.list(lowCodeConfigListDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO lowCodeInstall(LowCodeInstallDTO lowCodeInstallDTO) throws XbbException {
        String corpid = lowCodeInstallDTO.getCorpid();
        if (!packageHelp.isUltimateWithFeeType(corpid)){
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402008);
        }
        Long formId = lowCodeInstallDTO.getFormId();
        Integer businessType = lowCodeInstallDTO.getBusinessType();
        Integer saasMark = lowCodeInstallDTO.getSaasMark();
        String userId = lowCodeInstallDTO.getUserId();
        UserVO loginUser = getLoginUser(corpid, userId);
        Integer operationType = lowCodeInstallDTO.getOperationType();
        LowCodeConfigPojo lowCodeConfigPojo = lowCodeInstallDTO.getLowCodeConfigPojo();
        LowCodeJsFilePojo lowCodeFilePojo = lowCodeInstallDTO.getLowCodeFilePojo();
        LowCodeOperationTypeEnum operationTypeEnum = LowCodeOperationTypeEnum.getByType(operationType);
        if (Objects.isNull(operationTypeEnum)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }

        // 校验权限
        ProPermissionHelp.verifyPermission(loginUser, ProPermissionAliasEnum.FORM_SET_UPDATE.getAlias());
        developerService.verifyPermission(corpid, formId, loginUser, saasMark, businessType);

        switch (operationTypeEnum) {
            case INSTALL:
                install(corpid, loginUser, formId, saasMark, businessType, lowCodeConfigPojo, lowCodeFilePojo);
                break;
            case COVER:
                cover(corpid, loginUser, formId, saasMark, businessType, lowCodeConfigPojo, lowCodeFilePojo);
                break;
            default:
                break;
        }
        return new BaseVO();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO backLowCode(CloudCodeLowCodeConfigListDTO cloudCodeLowCodeConfigListDTO) throws XbbException {
        String corpid = cloudCodeLowCodeConfigListDTO.getCorpid();
        Long formId = cloudCodeLowCodeConfigListDTO.getFormId();
        Integer businessType = cloudCodeLowCodeConfigListDTO.getBusinessType();
        udpateAndDeleteLowCode(corpid, formId, businessType);
        return new BaseVO();
    }

    /**
     * 回退低代码
     * 去掉了OSS操作- OSS操作在模板中心
     * @param corpid
     * @param formId
     * @throws XbbException
     */
    private void udpateAndDeleteLowCode(String corpid, Long formId, Integer businessType) throws XbbException {

        // 获取备份
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("sourceFormId", formId);
        param.put("sourceFrom", BasicConstant.ONE);
        param.put(ParameterConstant.ORDER_BY_STR, " add_time DESC ");
        param.put(ParameterConstant.PAGE_SIZE, BasicConstant.ONE);
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            param.put("retainBusinessType", businessType);
        }

        List<LowCodeRetaionEntity> lowCodeRetaionEntityList = lowCodeRetaionModel.findEntities(param);
        if (CollectionsUtil.isEmpty(lowCodeRetaionEntityList)) {
            // 没有备份时，说明是初始状态安装，还原至初始状态
            deleteLowCode(corpid, formId, businessType);
            return;
        }
        LowCodeRetaionEntity lowCodeRetaionEntity = lowCodeRetaionEntityList.get(0);
        param.clear();
        param.put("corpid", corpid);
        param.put("formId", formId);
        if (Objects.nonNull(businessType)) {
            param.put(StringConstant.BUSINESS_TYPE, businessType);
        }
        List<LowCodeJsFileEntity> lowCodeJsFileEntityList = lowCodeJsFileModel.findEntitys(param);
        for (LowCodeJsFileEntity item : lowCodeJsFileEntityList) {
            if (!Objects.equals(item.getId(), lowCodeRetaionEntity.getSourceId())) {
                item.setDel(DelEnum.DELETE.getDel());
                continue;
            }
            item.setUpdateTime(lowCodeRetaionEntity.getUpdateTime());
            item.setFormId(lowCodeRetaionEntity.getSourceFormId());
            item.setSaasMark(lowCodeRetaionEntity.getSourceSaasMark());
            item.setBusinessType(lowCodeRetaionEntity.getSourceBusinessType());
            item.setWhetherToPublish(lowCodeRetaionEntity.getWhetherToPublish());
            item.setCreatorId(lowCodeRetaionEntity.getCreatorId());
            item.setDel(lowCodeRetaionEntity.getDel());
        }
        if (CollectionsUtil.isNotEmpty(lowCodeJsFileEntityList)){
            lowCodeJsFileModel.updateBatch(lowCodeJsFileEntityList, corpid);
        }
        // 回退低代码配置
        backLowCodeConfig(corpid, formId, lowCodeRetaionEntity, businessType);
    }

    /**
     * 回退低代码配置
     * @param corpid
     * @param lowCodeRetaionEntity
     */
    private void backLowCodeConfig(String corpid, Long formId, LowCodeRetaionEntity lowCodeRetaionEntity, Integer businessType) {


        String lowCodeConfig = lowCodeRetaionEntity.getLowCodeConfig();
        LowCodeConfigRetaionPojo lowCodeConfigRetaionPojo = JSONObject.parseObject(lowCodeConfig, LowCodeConfigRetaionPojo.class);
        List<CustomButtonPojo> customButtonPojoList = lowCodeConfigRetaionPojo.getCustomButtonPojoList();
        List<CustomButtonActionPojo> customButtonActionPojoList = new ArrayList<>();
        List<LowCodeActionSettingPojo> actionSettingList = lowCodeConfigRetaionPojo.getActionSettingList();


        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.FORM_ID, formId);
        if (Objects.nonNull(businessType)) {
            param.put(StringConstant.BUSINESS_TYPE, businessType);
        }
        List<CustomButtonEntity> customButtonEntityList = customButtonModel.findEntitys(param);
        List<CustomButtonActionEntity> customButtonActionEntityList = customButtonActionModel.findEntitys(param);
        List<LowCodeActionSettingEntity> lowCodeActionSettingEntityList = lowCodeActionSettingModel.findEntitys(param);

        // 低代码自定义按钮
        Map<Long, CustomButtonPojo> buttonPojoMap = new HashMap<>();
        if (CollectionsUtil.isNotEmpty(customButtonPojoList)) {
            buttonPojoMap = customButtonPojoList.stream().collect(Collectors.toMap(CustomButtonPojo::getId, t -> t, (t, t1) -> t1));
        }
        for (CustomButtonEntity customButtonEntity : customButtonEntityList) {
            CustomButtonPojo customButtonPojo = buttonPojoMap.get(customButtonEntity.getId());
            if (Objects.nonNull(customButtonPojo)) {
                customButtonEntity.setFormId(customButtonPojo.getFormId());
                customButtonEntity.setName(customButtonPojo.getName());
                customButtonEntity.setIcon(customButtonPojo.getIcon());
                customButtonEntity.setColor(customButtonPojo.getColor());
                customButtonEntity.setType(customButtonPojo.getType());
                customButtonEntity.setSort(customButtonPojo.getSort());
                customButtonEntity.setDel(DelEnum.NORMAL.getDel());
            } else {
                customButtonEntity.setDel(DelEnum.DELETE.getDel());
            }
        }

        // 按钮动作设置
        if (CollectionsUtil.isNotEmpty(customButtonPojoList)) {
            customButtonPojoList.forEach(item-> item.getActionList().forEach(action -> {
                action.setButtonId(item.getId());
                customButtonActionPojoList.add(action);
            }));
        }
        Map<Long, CustomButtonActionPojo> customButtonActionPojoMap = new HashMap<>();
        if (CollectionsUtil.isNotEmpty(customButtonActionPojoList)) {
            customButtonActionPojoMap = customButtonActionPojoList.stream().collect(Collectors.toMap(CustomButtonActionPojo::getId, t -> t, (t, t1) -> t1));
        }
        for (CustomButtonActionEntity customButtonActionEntity : customButtonActionEntityList) {
            CustomButtonActionPojo customButtonActionPojo = customButtonActionPojoMap.get(customButtonActionEntity.getId());
            if (Objects.nonNull(customButtonActionPojo)) {
                customButtonActionEntity.setFormId(customButtonActionPojo.getFormId());
                customButtonActionEntity.setButtonId(customButtonActionPojo.getButtonId());
                customButtonActionEntity.setActionType(customButtonActionPojo.getActionType());
                String customButtonActionPojoParam = Objects.isNull(customButtonActionPojo.getParam()) ? null : customButtonActionPojo.getParam().toJSONString();
                customButtonActionEntity.setParam(customButtonActionPojoParam);
                customButtonActionEntity.setSort(customButtonActionPojo.getSort());
                customButtonActionEntity.setDel(DelEnum.NORMAL.getDel());
            } else {
                customButtonActionEntity.setDel(DelEnum.DELETE.getDel());
            }
        }

        // 低代码动作设置
        Map<Long, LowCodeActionSettingPojo> lowCodeActionSettingPojoMap = new HashMap<>();
        if (CollectionsUtil.isNotEmpty(actionSettingList)) {
            lowCodeActionSettingPojoMap = actionSettingList.stream().collect(Collectors.toMap(LowCodeActionSettingPojo::getId, t -> t, (t, t1) -> t1));
        }
        for (LowCodeActionSettingEntity lowCodeActionSettingEntity : lowCodeActionSettingEntityList) {
            LowCodeActionSettingPojo lowCodeActionSettingPojo = lowCodeActionSettingPojoMap.get(lowCodeActionSettingEntity.getId());
            if (Objects.nonNull(lowCodeActionSettingPojo)) {
                lowCodeActionSettingEntity.setType(lowCodeActionSettingPojo.getType());
                lowCodeActionSettingEntity.setTriggerTiming(lowCodeActionSettingPojo.getTriggerTiming());
                lowCodeActionSettingEntity.setActionType(lowCodeActionSettingPojo.getActionType());
                lowCodeActionSettingEntity.setAttr(lowCodeActionSettingPojo.getAttr());
                lowCodeActionSettingEntity.setFieldType(lowCodeActionSettingPojo.getFieldType());
                String lowCodeActionSettingPojoParam = Objects.isNull(lowCodeActionSettingPojo.getParam()) ? null : lowCodeActionSettingPojo.getParam().toJSONString();
                lowCodeActionSettingEntity.setParam(lowCodeActionSettingPojoParam);
                lowCodeActionSettingEntity.setSort(lowCodeActionSettingPojo.getSort());
                lowCodeActionSettingEntity.setDel(DelEnum.NORMAL.getDel());
            } else {
                lowCodeActionSettingEntity.setDel(DelEnum.DELETE.getDel());
            }
        }

        //入库
        if (CollectionsUtil.isNotEmpty(customButtonEntityList)) {
            customButtonModel.updateBatch(customButtonEntityList, corpid);
        }
        if (CollectionsUtil.isNotEmpty(customButtonActionEntityList)) {
            customButtonActionModel.updateBatch(customButtonActionEntityList, corpid);
        }
        if (CollectionsUtil.isNotEmpty(lowCodeActionSettingEntityList)) {
            lowCodeActionSettingModel.updateBatch(lowCodeActionSettingEntityList, corpid);
        }
    }

    /**
     * 初次安装
     * @param corpid 公司id
     * @param userVO 登录用户
     * @param formId 表单id
     * @param saasMark saas标记
     * @param businessType 业务类型
     * @param lowCodeConfigPojo 低代码配置
     * @param lowCodeFilePojo 低代码表单配置
     * @throws XbbException exception
     */
    private void install(String corpid, UserVO userVO, Long formId, Integer saasMark, Integer businessType, LowCodeConfigPojo lowCodeConfigPojo, LowCodeJsFilePojo lowCodeFilePojo) throws XbbException {
        LowCodeConfigListDTO lowCodeConfigListDTO = new LowCodeConfigListDTO();
        lowCodeConfigListDTO.setLoginUser(userVO);
        lowCodeConfigListDTO.setCorpid(corpid);
        lowCodeConfigListDTO.setFormId(formId);
        lowCodeConfigListDTO.setBusinessType(businessType);
        lowCodeConfigListDTO.setSaasMark(saasMark);
        lowCodeConfigListDTO.setUserId(userVO.getUserId());
        LowCodeConfigListVO lowCodeConfigListVO = lowCodeConfigService.list(lowCodeConfigListDTO);

        if (CollectionsUtil.isNotEmpty(lowCodeConfigListVO.getServiceList())
                || CollectionsUtil.isNotEmpty(lowCodeConfigListVO.getCustomButtonList())
                || (Objects.nonNull(lowCodeConfigListVO.getActionList()) && !lowCodeConfigListVO.getActionList().isEmpty())
                || (Objects.nonNull(lowCodeConfigListVO.getLowCodeJsFile())) && Objects.nonNull(lowCodeConfigListVO.getLowCodeJsFile().getFileId())) {
            throw new XbbException(PerformanceErrorCodeEnum.API_ERROR_240014, String.format(PerformanceErrorCodeEnum.API_ERROR_240014.getMsg(), "低代码", "选择覆盖或合并"));
        }
        lowCodeRetaion(corpid, formId, saasMark, businessType);
        saveLowCodeConfig(corpid, userVO.getUserId(), formId, saasMark, businessType, lowCodeConfigPojo);
        saveLowCodeFile(corpid, userVO.getUserId(), formId, saasMark, businessType, lowCodeFilePojo);
    }

    /**
     * 覆盖
     * 当前方案为：备份旧数据后，统一删掉旧数据，安装新数据
     * @param corpid 公司id
     * @param userVO 登录用户
     * @param formId 表单id
     * @param saasMark saas标记
     * @param businessType 业务类型
     * @param lowCodeConfigPojo 低代码配置
     * @param lowCodeFilePojo 低代码文件配置
     * @throws XbbException exception
     */
    private void cover(String corpid, UserVO userVO, Long formId, Integer saasMark, Integer businessType, LowCodeConfigPojo lowCodeConfigPojo, LowCodeJsFilePojo lowCodeFilePojo) throws XbbException {
        // 备份
        lowCodeRetaion(corpid, formId, saasMark, businessType);

        deleteLowCode(corpid, formId, businessType);
        saveLowCodeConfig(corpid, userVO.getUserId(), formId, saasMark, businessType, lowCodeConfigPojo);
        saveLowCodeFile(corpid, userVO.getUserId(), formId, saasMark, businessType, lowCodeFilePojo);
    }

    /**
     * 删除低代码
     * @param corpid 公司id
     * @param formId 表单id
     * @param businessType 业务类型
     */
    private void deleteLowCode(String corpid, Long formId, Integer businessType) {
        customButtonModel.deleteByFormId(formId, corpid, businessType);
        customButtonActionModel.deleteFormId(formId, corpid, businessType);
        lowCodeActionSettingModel.deleteByFormId(formId, corpid, businessType);
        lowCodeJsFileModel.deleteByFormId(formId, corpid, businessType);
    }

    /**
     * 备份低代码及低代码配置
     * @param corpid 公司id
     * @param formId 表单id
     * @param saasMark saas标记
     * @param businessType 业务类型
     * @throws XbbException exception
     */
    private void lowCodeRetaion(String corpid, Long formId, Integer saasMark, Integer businessType) throws XbbException {
        List<CustomButtonPojo> customButtonPojoList = getButtonList(corpid, formId, businessType);
        List<LowCodeActionSettingPojo> actionSettingList = getActionSettingList(corpid, formId, businessType);
        List<LowCodeJsFileEntity> lowCodeJsFileEntityList = getJsFileList(corpid, formId, businessType);
        LowCodeRetaionEntity lowCodeRetaionEntity = new LowCodeRetaionEntity();
        lowCodeRetaionEntity.setSourceFrom(BasicConstant.ONE);
        if (CollectionsUtil.isEmpty(lowCodeJsFileEntityList)) {
            return;
        }
        LowCodeJsFileEntity lowCodeJsFileEntity = lowCodeJsFileEntityList.get(0);
        lowCodeRetaionEntity.setCorpid(corpid);
        lowCodeRetaionEntity.setSourceFormId(formId);
        lowCodeRetaionEntity.setSourceId(lowCodeJsFileEntity.getId());
        lowCodeRetaionEntity.setSourceSaasMark(saasMark);
        lowCodeRetaionEntity.setSourceBusinessType(businessType);

        //拷贝低代码文件
        if (Objects.isNull(lowCodeJsFileEntity.getPublish()) || StringUtil.isEmpty(lowCodeJsFileEntity.getPublish()) || Objects.equals(lowCodeJsFileEntity.getPublish(), "null")) {
            lowCodeJsFileEntity.setPublish(lowCodeJsFileEntity.getPublish());
        } else {
            lowCodeRetaionEntity.setPublish(lowCodeJsFileEntity.getUnreleased());
        }

        lowCodeRetaionEntity.setWhetherToPublish(lowCodeJsFileEntity.getWhetherToPublish());
        lowCodeRetaionEntity.setCreatorId(lowCodeJsFileEntity.getCreatorId());
        long now = DateTimeUtil.getInt();
        lowCodeRetaionEntity.setAddTime(now);
        lowCodeRetaionEntity.setUpdateTime(now);
        lowCodeRetaionEntity.setDel(DelEnum.NORMAL.getDel());

        // 低代码配置
        LowCodeConfigRetaionPojo lowCodeConfigRetaionPojo = new LowCodeConfigRetaionPojo();
        lowCodeConfigRetaionPojo.setCustomButtonPojoList(customButtonPojoList);
        lowCodeConfigRetaionPojo.setActionSettingList(actionSettingList);
        lowCodeRetaionEntity.setLowCodeConfig(JSONObject.toJSONString(lowCodeConfigRetaionPojo));
        lowCodeRetaionModel.insert(lowCodeRetaionEntity);
    }

    /**
     * 获取自定义按钮列表
     * @param corpid 公司id
     * @param formId 表单id
     * @param businessType 业务类型
     * @return 自定义按钮封装
     * @throws XbbException exception
     */
    public List<CustomButtonPojo> getButtonList(String corpid, Long formId, Integer businessType) throws XbbException {
        List<CustomButtonPojo> customButtonList = new ArrayList<>();
        try {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(StringConstant.FORM_ID, formId);
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                param.put(StringConstant.BUSINESS_TYPE, businessType);
            }
            List<CustomButtonEntity> buttonList = customButtonModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(buttonList)) {
                return new ArrayList<>();
            }

            List<Long> buttonIdList = buttonList.stream().map(CustomButtonEntity::getId).collect(Collectors.toList());
            Map<Long, List<CustomButtonActionPojo>> actionMap = new HashMap<>(buttonList.size());

            param.put("buttonIdIn", buttonIdList);
            List<CustomButtonActionEntity> buttonActionList = customButtonActionModel.findEntitys(param);
            buttonActionList.forEach(item -> {
                if (actionMap.containsKey(item.getButtonId())) {
                    List<CustomButtonActionPojo> customButtonActionList = actionMap.get(item.getButtonId());
                    CustomButtonActionPojo customButtonActionPojo = new CustomButtonActionPojo(item.getId(), item.getButtonId(), item.getActionType(), JSON.parseObject(item.getParam()), item.getSort());
                    customButtonActionList.add(customButtonActionPojo);
                    actionMap.put(item.getButtonId(), customButtonActionList);
                } else {
                    List<CustomButtonActionPojo> customButtonActionList = new ArrayList<>();
                    CustomButtonActionPojo customButtonActionPojo = new CustomButtonActionPojo(item.getId(), item.getButtonId(), item.getActionType(), JSON.parseObject(item.getParam()), item.getSort());
                    customButtonActionList.add(customButtonActionPojo);
                    actionMap.put(item.getButtonId(), customButtonActionList);
                }
            });
            buttonList.forEach(item -> {
                CustomButtonPojo customButtonPojo = new CustomButtonPojo(item.getId(), item.getName(), item.getIcon(), item.getColor(), item.getType(), item.getSort(), actionMap.get(item.getId()));
                customButtonList.add(customButtonPojo);
            });
            return customButtonList;
        } catch (Exception e) {
            LOG.error("CloudCodeServiceImpl.getButtonList error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 获取低代码动作配置列表
     * @param corpid 公司id
     * @param formId 表单id
     * @param businessType 业务类型
     * @return 低代码动作配置列表
     * @throws XbbException exception
     */
    public List<LowCodeActionSettingPojo> getActionSettingList(String corpid, Long formId, Integer businessType) throws XbbException {
        List<LowCodeActionSettingPojo> lowCodeActionSettingPojoList = new ArrayList<>();
        try {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.FORM_ID, formId);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                param.put(StringConstant.BUSINESS_TYPE, businessType);
            }
            param.put(ParameterConstant.ORDER_BY_STR, "sort ASC");
            List<LowCodeActionSettingEntity> lowCodeActionSettingList = lowCodeActionSettingModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(lowCodeActionSettingList)) {
                return lowCodeActionSettingPojoList;
            }
            lowCodeActionSettingList.forEach(item -> {
                LowCodeActionSettingPojo lowCodeActionSettingPojo = new LowCodeActionSettingPojo(item.getId(), item.getType(), item.getTriggerTiming(), item.getActionType(), item.getAttr(), item.getFieldType(), JSON.parseObject(item.getParam()), item.getSort());
                lowCodeActionSettingPojoList.add(lowCodeActionSettingPojo);
            });
            return lowCodeActionSettingPojoList;
        }  catch (Exception e) {
            LOG.error("CloudCodeServiceImpl.getActionSettingList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 获取低代码文件列表
     * @param corpid 公司id
     * @param formId 表单id
     * @param businessType 业务类型
     * @return 低代码文件列表
     * @throws XbbException exception
     */
    public List<LowCodeJsFileEntity> getJsFileList(String corpid, Long formId, Integer businessType) throws XbbException {
        try {

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.FORM_ID, formId);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                param.put(StringConstant.BUSINESS_TYPE, businessType);
            }
            return lowCodeJsFileModel.findEntitys(param);
        } catch (Exception e) {
            LOG.error("CloudCodeServiceImpl.getJsFileList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 保存低代码配置
     * @param corpid 公司id
     * @param formId 表单id
     * @param saasMark saas标志
     * @param businessType 业务类型
     * @param lowCodeConfigPojo 低代码配置
     * @throws XbbException exception
     */
    private void saveLowCodeConfig(String corpid, String userId, Long formId, Integer saasMark, Integer businessType, LowCodeConfigPojo lowCodeConfigPojo) throws XbbException {
        //表单按钮
        saveCustomerButton(corpid, userId, formId, saasMark, businessType, lowCodeConfigPojo.getCustomButtonList());
        //字段动作
        saveActionSetting(corpid, userId, formId, saasMark, businessType, lowCodeConfigPojo.getLowCodeActionSettingList());
    }

    /**
     * 保存自定义按钮
     * @param corpid 公司id
     * @param userId 登录用户
     * @param formId 表单Id
     * @param saasMark saas标记
     * @param businessType 业务类型
     * @param customButtonPojoList 自定义按钮list
     * @throws XbbException exception
     */
    private void saveCustomerButton(String corpid, String userId, Long formId, Integer saasMark, Integer businessType, List<CustomButtonPojo> customButtonPojoList) throws XbbException {
        if (CollectionsUtil.isEmpty(customButtonPojoList)) {
            return;
        }
        List<CustomButtonEntity> addList = new ArrayList<>(customButtonPojoList.size());
        List<CustomButtonActionEntity> actionAddList = new ArrayList<>();

        for (CustomButtonPojo customButton : customButtonPojoList) {
            long now = DateTimeUtil.getInt();
            List<CustomButtonActionEntity> actionList = new ArrayList<>();
            CustomButtonEntity customButtonEntity = new CustomButtonEntity(corpid, formId, saasMark, businessType, customButton.getName(), customButton.getIcon(), customButton.getColor(),
                    customButton.getType(), customButton.getSort(), userId, now, now);
            if (Objects.nonNull(customButton.getActionList())) {
                for (CustomButtonActionPojo action : customButton.getActionList()) {
                    if (Objects.equals(action.getActionType(), LowCodeActionTypeEnum.API_SERVICE.getCode()) ||
                            Objects.equals(action.getActionType(), LowCodeActionTypeEnum.INITIATE_REQUEST.getCode())) {
                        continue;
                    }
                    Long serviceId = 0L;
                    CustomButtonActionEntity customButtonActionEntity = new CustomButtonActionEntity(corpid, formId, saasMark, businessType, 0L, action.getActionType(), serviceId,
                            JSON.toJSONString(action.getParam()), action.getSort(), userId, now, now);
                    actionList.add(customButtonActionEntity);
                }
            }
            if (CollectionsUtil.isNotEmpty(actionList)) {
                customButtonEntity.setActionList(actionList);
                addList.add(customButtonEntity);
            }
        }

        //入库
        if (CollectionsUtil.isNotEmpty(addList)) {
            customButtonModel.insertBatch(addList);
            addList.forEach(item-> item.getActionList().forEach(action -> {
                action.setButtonId(item.getId());
                actionAddList.add(action);
            }));
        }
        if (CollectionsUtil.isNotEmpty(actionAddList)) {
            customButtonActionModel.insertBatch(actionAddList);
        }
    }

    /**
     * 保存低代码动作设置
     * @param corpid 公司id
     * @param userId 登录用户
     * @param formId 表单id
     * @param saasMark saas标记
     * @param businessType 业务类型
     * @param lowCodeActionSettingList 低代码动作配置
     * @throws XbbException exception
     */
    private void saveActionSetting(String corpid, String userId, Long formId, Integer saasMark, Integer businessType, List<LowCodeActionSettingPojo> lowCodeActionSettingList) throws XbbException {
        if (CollectionsUtil.isEmpty(lowCodeActionSettingList)) {
            return;
        }
        List<LowCodeActionSettingEntity> addList = new ArrayList<>(lowCodeActionSettingList.size());
        for (LowCodeActionSettingPojo item : lowCodeActionSettingList) {
            if (Objects.equals(item.getActionType(), LowCodeActionTypeEnum.API_SERVICE.getCode()) ||
                    Objects.equals(item.getActionType(), LowCodeActionTypeEnum.INITIATE_REQUEST.getCode())) {
                continue;
            }
            Long serviceId = 0L;
            long now = DateTimeUtil.getInt();
            LowCodeActionSettingEntity lowCodeActionSettingEntity = new LowCodeActionSettingEntity(corpid, formId, saasMark, businessType, item.getType(), item.getTriggerTiming(),
                    item.getActionType(), item.getAttr(), item.getFieldType(), serviceId,
                    JSON.toJSONString(item.getParam()), item.getSort(), userId, now, now);
            addList.add(lowCodeActionSettingEntity);

        }
        if (CollectionsUtil.isNotEmpty(addList)) {
            lowCodeActionSettingModel.addBatch(addList);
        }
    }

    /**
     * 保存低代码文件
     * @param corpid 公司id
     * @param userId 登录用户
     * @param formId 表单id
     * @param saasMark saas标志
     * @param businessType 业务类型
     * @param lowCodeFilePojo 低代码文件
     * @throws XbbException exception
     */
    private void saveLowCodeFile(String corpid, String userId, Long formId, Integer saasMark, Integer businessType, LowCodeJsFilePojo lowCodeFilePojo) throws XbbException {
        try {
            LowCodeJsFileEntity lowCodeJsFileEntity = new LowCodeJsFileEntity(corpid, formId, saasMark, businessType,
                    JSON.toJSONString(lowCodeFilePojo.getUnreleased()), JSON.toJSONString(lowCodeFilePojo.getRelease()), lowCodeFilePojo.getWhetherToPublish(), userId);
            lowCodeJsFileModel.insert(lowCodeJsFileEntity);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("LowCodeJsFileServiceImpl.saveLowCodeFile 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 获取当前登录用户
     * @param corpid 公司id
     * @param userId 用户id
     * @return userVO
     * @throws XbbException exception
     */
    private UserVO getLoginUser(String corpid, String userId) throws XbbException {
        UserVO user = null;
        // 增加缓存，不用每次访问接口获取权限
        String loginUserKey = corpid + "____" + userId;
        String userVOStr = paasRedisHelper.getValue(RedisPrefixConstant.PAAS_LOGIN_USER_INFO, loginUserKey);
        if (!StringUtil.isEmpty(userVOStr)) {
            user = JSON.parseObject(userVOStr, UserVO.class);
        }
        if (user == null || Objects.isNull(user.getDataPermissionDetail())) {
            //获取用户和权限信息
            UserInfoDTO userInfoDTO = new UserInfoDTO();
            userInfoDTO.setCorpid(corpid);
            userInfoDTO.setUserId(userId);
            userInfoDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());
            userInfoDTO.setPaasPermissionsFlag(true);
            userInfoDTO.setUserDetailFlag(true);
            userInfoDTO.setCompanyInfoFlag(false);
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            XbbResponse<UserInfoVO> userInfoResp = userFeignClient.getUserInfo(userInfoDTO, lang);
            UserInfoVO userInfo;
            if (userInfoResp.isSuccess()) {
                userInfo = userInfoResp.getResult();
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004);
            }
            user = userInfo.getUser();
            paasRedisHelper.setValue(RedisPrefixConstant.PAAS_LOGIN_USER_INFO, loginUserKey, user, TimeConstant.SEARCH_EFFECTIVE_TIME);
        }
        return user;
    }
}
